﻿using Microsoft.Extensions.Logging;
using RotovapPlatform.Domain.Equipment.Device.IO;
using RotovapPlatform.Domain.Equipment.Device.Motors.Dto;
using RotovapPlatform.Domain.Equipment.Device.Robot.Dto;
using RotovapPlatform.Domain.Equipment.Device.TCU.Dto;
using RotovapPlatform.Domain.Equipment.Device.OilBath.Dto;
using RotovapPlatform.Domain.Equipment.Device.TemperatureCollector.Dto;
using RotovapPlatform.Domain.Equipment.Interfaces.Services;
using System.Collections.Concurrent;
using RotovapPlatform.Domain.Equipment.Interfaces.Base;
using RotovapPlatform.Domain.Common;
using RotovapPlatform.Domain.Equipment.Device.Valves.Dto;
using RotovapPlatform.Domain.Equipment.Interfaces.Communication;
using RotovapPlatform.Domain.Common.Exceptions;

namespace RotovapPlatform.Application.Services.Devices
{
	/// <summary>
	/// 设备状态服务：负责所有设备的状态监控和状态缓存
	/// </summary>
	public class DeviceStatusService : IDeviceStatusService, IDisposable
	{
		private readonly IDeviceManager _deviceManager;
		private readonly IMotorControlService _motorControlService;
		private readonly IIOSignalAppService _ioSignalAppService;
		private readonly ISerialServerManager _serialServerManager;
		private readonly ILogger<DeviceStatusService> _logger;
		private readonly object _lockObject = new();
		private readonly CancellationTokenSource _cts = new();
		private Task _monitoringTask;
		private bool _disposed;

		// 设备状态缓存
		private readonly ConcurrentDictionary<string, MotorStatus> _motorStatuses = new();
		private readonly ConcurrentDictionary<string, TCUStatus> _tcuStatuses = new();
		private readonly ConcurrentDictionary<string, OilBathStatus> _oilBathStatuses = new(); // 油浴锅状态缓存
		private readonly ConcurrentDictionary<string, TemperatureCollectorStatus> _temperatureCollectorStatuses = new(); // 温度采集模块状态缓存
		private readonly ConcurrentDictionary<string, ValveStatus> _valveStatuses = new(); // 切换阀状态缓存
		private volatile RobotStatusDto _robotDeviceStatus;
		private volatile RobotTaskFeedBackDto _robotTaskStatus;

		// 设备状态变化事件
		public event EventHandler<DeviceStatusEventArgs> DeviceStatusChanged;

		// 状态回调函数
		private readonly List<Func<string, object, Task>> _statusCallbacks = new();

		public DeviceStatusService(
			IDeviceManager deviceManager,
			IMotorControlService motorControlService,
			IIOSignalAppService ioSignalAppService,
			ISerialServerManager serialServerManager,
			ILogger<DeviceStatusService> logger)
		{
			_deviceManager = deviceManager;
			_motorControlService = motorControlService;
			_ioSignalAppService = ioSignalAppService;
			_serialServerManager = serialServerManager;
			_logger = logger;

			// 注册IO信号状态变化回调
			if (_ioSignalAppService != null)
			{
				_ioSignalAppService.SignalStateChanged += OnIOSignalStateChanged;
			}
		}

		public async Task StartMonitoringAsync()
		{
			try
			{
				_logger.LogInformation("开始启动设备状态监控");

				// 启动IO信号服务
				if (_ioSignalAppService != null)
				{
					await _ioSignalAppService.StartAsync();
					_logger.LogInformation("IO信号服务启动成功");
				}

				if (_monitoringTask != null)
				{
					_logger.LogInformation("状态监控任务已在运行");
					return;
				}

				_monitoringTask = MonitorDeviceStatusAsync(_cts.Token);
				_logger.LogInformation("设备状态监控启动成功");
				await Task.CompletedTask;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "启动设备状态监控失败");
				throw;
			}
		}

		public async Task StopMonitoringAsync()
		{
			try
			{
				_logger.LogInformation("开始停止设备状态监控");

				if (_monitoringTask == null)
				{
					_logger.LogInformation("没有正在运行的状态监控任务");
					return;
				}

				_cts.Cancel();
				await _monitoringTask;
				_monitoringTask = null;
				_logger.LogInformation("状态监控任务已停止");

				// 停止IO信号服务
				if (_ioSignalAppService != null)
				{
					await _ioSignalAppService.StopAsync();
					_logger.LogInformation("IO信号服务已停止");
				}

				_logger.LogInformation("设备状态监控已完全停止");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "停止设备状态监控失败");
				throw;
			}
		}

		private async Task MonitorDeviceStatusAsync(CancellationToken ct)
		{
			_logger.LogInformation("设备状态监控循环开始");

			while (!ct.IsCancellationRequested)
			{
				try
				{
					await UpdateAllDeviceStatusAsync();
					await Task.Delay(1000, ct);
				}
				catch (OperationCanceledException)
				{
					_logger.LogInformation("设备状态监控循环被取消");
					break;
				}
				catch (CommunicationException comEx)
				{
					// 通信异常特殊处理，打印警告但继续循环
					_logger.LogWarning(comEx, "设备通信异常，将在下次循环重试");
					await Task.Delay(1000, ct); // 适当延长重试间隔
				}
				catch (Exception ex)
				{
					_logger.LogError(ex, "设备状态监控异常");
					await Task.Delay(1000, ct);
				}

			}

			_logger.LogInformation("设备状态监控循环结束");
		}

		public async Task UpdateAllDeviceStatusAsync()
		{
			try
			{
				await _deviceManager.UpdateAllAxisStatusAsync();

				// 检查串口服务器连接状态
				if (_serialServerManager != null)
				{
					try
					{
						bool isConnected = _serialServerManager.IsConnected;
						OnDeviceStatusChanged(new DeviceStatusEventArgs("SerialServerConnection", isConnected));

						// 如果连接中断，尝试重连
						if (!isConnected)
						{
							_logger.LogWarning("串口服务器连接已断开，尝试重新连接...");
							await _serialServerManager.CheckConnectionAsync();
						}
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, "获取串口服务器状态失败");
					}
				}

				//// 更新电机状态 - 优先使用电机控制服务
				//try
				//{
				//	var motors = await _motorControlService.GetMotorsAsync();
				//	foreach (var motor in motors)
				//	{
				//		try
				//		{
				//			var status = await _motorControlService.GetMotorStatusAsync(motor.EquipmentId);
				//			UpdateDeviceStatus(motor.EquipmentId, status, _motorStatuses);
				//		}
				//		catch (Exception ex)
				//		{
				//			_logger.LogWarning(ex, $"使用电机控制服务获取电机 {motor.EquipmentId} 状态失败");
				//		}
				//	}
				//}
				//catch (Exception ex)
				//{
				//	_logger.LogWarning(ex, "使用电机控制服务获取电机状态失败，使用设备管理器获取");

				//	// 如果电机控制服务失败，回退到使用设备管理器
				//	foreach (var motor in _deviceManager.Motors.Values)
				//	{
				//		try
				//		{
				//			var status = await motor.GetStatusAsync();
				//			UpdateDeviceStatus(motor.EquipmentId, status, _motorStatuses);
				//		}
				//		catch (Exception motorEx)
				//		{
				//			_logger.LogError(motorEx, $"获取电机 {motor.EquipmentId} 状态失败");
				//		}
				//	}
				//}

				//// 更新TCU状态
				//foreach (var tcu in _deviceManager.TCUs.Values)
				//{
				//	try
				//	{
				//		var status = await tcu.GetTCUStatusAsync();
				//		UpdateDeviceStatus(tcu.EquipmentId, status, _tcuStatuses);
				//	}
				//	catch (Exception ex)
				//	{
				//		_logger.LogError(ex, $"获取TCU {tcu.EquipmentId} 状态失败");
				//	}
				//}

				//更新油浴锅状态
				foreach (var oilBath in _deviceManager.OilBaths.Values)
				{
					try
					{
						var status = await oilBath.GetOilBathStatusAsync();
						UpdateDeviceStatus(oilBath.EquipmentId, status, _oilBathStatuses);
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, $"获取油浴锅 {oilBath.EquipmentId} 状态失败");
					}
				}

				//更新温度采集模块状态
				foreach (var collector in _deviceManager.TemperatureCollectors.Values)
				{
					try
					{
						var status = await collector.GetTemperatureCollectorStatusAsync();
						UpdateDeviceStatus(collector.EquipmentId, status, _temperatureCollectorStatuses);
					}
					catch (CommunicationException cex)
					{
						// 创建离线状态
						var offlineStatus = new TemperatureCollectorStatus
						{
							// 设置必要的离线状态属性
							IsConnected = false
						};

						// 更新状态为离线
						UpdateDeviceStatus(collector.EquipmentId, offlineStatus, _temperatureCollectorStatuses);
						_logger.LogWarning(cex, $"温度采集模块 {collector.EquipmentId} 通信异常，已标记为离线");
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, $"获取温度采集模块 {collector.EquipmentId} 状态失败");
					}
				}

				//更新切换阀状态
				foreach (var valve in _deviceManager.Valves.Values)
				{
					try
					{
						var status = await valve.GetValveStatusAsync();
						UpdateDeviceStatus(valve.EquipmentId, status, _valveStatuses);
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, $"获取切换阀 {valve.EquipmentId} 状态失败");
					}
				}

				// 更新机器人状态
				try
				{
					var robot = _deviceManager.Robot;
					var (taskFeedback, deviceStatus) = await robot.GetStatusAsync();
					UpdateRobotStatus(taskFeedback, deviceStatus);
				}
				catch (Exception ex)
				{
					_logger.LogError(ex, "获取机器人状态失败");
				}

				//更新IO信号状态
				try
				{
					if (_ioSignalAppService != null)
					{
						await _ioSignalAppService.RefreshAllSignalsAsync();

						// 获取冷凝器压力值并更新状态
						double condenserPressure = _ioSignalAppService.GetCondenserPressure();
						OnDeviceStatusChanged(new DeviceStatusEventArgs("CondenserPressure", condenserPressure));

						// 获取紧急停止信号状态
						bool emergencyStop = _ioSignalAppService.GetDIState(DISignalId.EmergencyStop);
						OnDeviceStatusChanged(new DeviceStatusEventArgs("EmergencyStop", emergencyStop));
					}
				}
				catch (Exception ex)
				{
					_logger.LogError(ex, "更新IO信号状态失败");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "更新设备状态失败");
				throw;
			}
		}

		/// <summary>
		/// 获取电机状态 - 优先使用电机控制服务
		/// </summary>
		public async Task<MotorStatus> GetMotorStatusAsync(string motorId)
		{
			if (string.IsNullOrEmpty(motorId))
			{
				_logger.LogWarning("获取电机状态时传入的电机ID为空");
				return new MotorStatus { Offline = true };
			}

			// 首先检查缓存
			if (_motorStatuses.TryGetValue(motorId, out var cachedStatus))
			{
				return cachedStatus;
			}

			try
			{
				// 优先使用电机控制服务获取状态
				_logger.LogDebug($"尝试使用电机控制服务获取电机 {motorId} 状态");
				var status = await _motorControlService.GetMotorStatusAsync(motorId);
				_motorStatuses[motorId] = status;
				return status;
			}
			catch (Exception ex)
			{
				_logger.LogWarning(ex, $"使用电机控制服务获取电机 {motorId} 状态失败，尝试使用设备管理器");

				try
				{
					// 如果电机控制服务失败，回退到使用设备管理器
					var motor = _deviceManager.GetMotor(motorId);
					var status = await motor.GetStatusAsync();
					_motorStatuses[motorId] = status;
					return status;
				}
				catch (Exception deviceEx)
				{
					_logger.LogError(deviceEx, $"获取电机 {motorId} 状态失败");
					return new MotorStatus { Offline = true };
				}
			}
		}

		/// <summary>
		/// 获取TCU状态
		/// </summary>
		public async Task<TCUStatus> GetTCUStatusAsync(string tcuId)
		{
			if (string.IsNullOrEmpty(tcuId))
			{
				_logger.LogWarning("获取TCU状态时传入的TCU ID为空");
				return new TCUStatus();
			}

			if (_tcuStatuses.TryGetValue(tcuId, out var cachedStatus))
			{
				return cachedStatus;
			}

			try
			{
				var tcu = _deviceManager.GetTCU(tcuId);
				if (tcu == null)
				{
					_logger.LogWarning($"未找到TCU: {tcuId}");
					return new TCUStatus();
				}

				var status = await tcu.GetTCUStatusAsync();
				_tcuStatuses[tcuId] = status;
				return status;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"获取TCU {tcuId} 状态失败");
				return new TCUStatus();
			}
		}

		/// <summary>
		/// 获取油浴锅状态
		/// </summary>
		public async Task<OilBathStatus> GetOilBathStatusAsync(string oilBathId)
		{
			if (string.IsNullOrEmpty(oilBathId))
			{
				_logger.LogWarning("获取油浴锅状态时传入的油浴锅ID为空");
				return new OilBathStatus();
			}

			if (_oilBathStatuses.TryGetValue(oilBathId, out var cachedStatus))
			{
				return cachedStatus;
			}

			try
			{
				var oilBath = _deviceManager.GetOilBath(oilBathId);
				if (oilBath == null)
				{
					_logger.LogWarning($"未找到油浴锅: {oilBathId}");
					return new OilBathStatus();
				}

				var status = await oilBath.GetOilBathStatusAsync();
				_oilBathStatuses[oilBathId] = status;
				return status;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"获取油浴锅 {oilBathId} 状态失败");
				return new OilBathStatus();
			}
		}

		/// <summary>
		/// 获取温度采集模块状态
		/// </summary>
		public async Task<TemperatureCollectorStatus> GetTemperatureCollectorStatusAsync(string collectorId)
		{
			if (string.IsNullOrEmpty(collectorId))
			{
				_logger.LogWarning("获取温度采集模块状态时传入的模块ID为空");
				return new TemperatureCollectorStatus();
			}

			if (_temperatureCollectorStatuses.TryGetValue(collectorId, out var cachedStatus))
			{
				return cachedStatus;
			}

			try
			{
				var collector = _deviceManager.GetTemperatureCollector(collectorId);
				if (collector == null)
				{
					_logger.LogWarning($"未找到温度采集模块: {collectorId}");
					return new TemperatureCollectorStatus();
				}

				var status = await collector.GetTemperatureCollectorStatusAsync();
				_temperatureCollectorStatuses[collectorId] = status;
				return status;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"获取温度采集模块 {collectorId} 状态失败");
				return new TemperatureCollectorStatus();
			}
		}

		/// <summary>
		/// 获取切换阀状态
		/// </summary>
		public async Task<ValveStatus> GetValveStatusAsync(string valveId)
		{
			if (string.IsNullOrEmpty(valveId))
			{
				_logger.LogWarning("获取切换阀状态时传入的切换阀ID为空");
				return new ValveStatus { CurrentChannel = -1 };
			}

			if (_valveStatuses.TryGetValue(valveId, out var cachedStatus))
			{
				return cachedStatus;
			}

			try
			{
				var valve = _deviceManager.GetValve(valveId);
				if (valve == null)
				{
					_logger.LogWarning($"未找到切换阀: {valveId}");
					return new ValveStatus { CurrentChannel = -1 };
				}

				var status = await valve.GetValveStatusAsync();
				_valveStatuses[valveId] = status;
				return status;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"获取切换阀 {valveId} 状态失败");
				return new ValveStatus { CurrentChannel = -1 };
			}
		}

		/// <summary>
		/// 获取机器人状态
		/// </summary>
		public async Task<(RobotTaskFeedBackDto TaskFeedback, RobotStatusDto DeviceStatus)> GetRobotStatusAsync()
		{
			try
			{
				var robot = _deviceManager.Robot;
				return await robot.GetStatusAsync();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取机器人状态失败");
				return (new RobotTaskFeedBackDto(), new RobotStatusDto());
			}
		}

		/// <summary>
		/// 获取IO信号状态
		/// </summary>
		public IDISignal GetDISignal(DISignalId id)
		{
			if (_ioSignalAppService == null)
			{
				_logger.LogWarning($"IO信号服务不可用，无法获取DI信号: {id}");
				return null;
			}

			return _ioSignalAppService.GetDISignal(id);
		}

		/// <summary>
		/// 获取IO信号状态
		/// </summary>
		public IDOSignal GetDOSignal(DOSignalId id)
		{
			if (_ioSignalAppService == null)
			{
				_logger.LogWarning($"IO信号服务不可用，无法获取DO信号: {id}");
				return null;
			}

			return _ioSignalAppService.GetDOSignal(id);
		}

		/// <summary>
		/// 设置DO信号状态
		/// </summary>
		public async Task<OperationResult> SetDOSignalStateAsync(DOSignalId id, bool state)
		{
			if (_ioSignalAppService == null)
			{
				_logger.LogWarning($"IO信号服务不可用，无法设置DO信号: {id}");
				return OperationResult.Fail($"IO信号服务不可用，无法设置DO信号: {id}");
			}

			if (await _ioSignalAppService.SetDOStateAsync(id, state))
			{
				return OperationResult.Ok($"设置DO信号: {id} 状态成功");
			}
			else
			{
				return OperationResult.Fail($"设置DO信号: {id} 状态失败");
			}
		}

		/// <summary>
		/// 获取冷凝器压力值
		/// </summary>
		public double GetCondenserPressure()
		{
			if (_ioSignalAppService == null)
			{
				_logger.LogWarning("IO信号服务不可用，无法获取冷凝器压力值");
				return 0;
			}

			return _ioSignalAppService.GetCondenserPressure();
		}

		private void UpdateDeviceStatus<T>(string deviceId, T newStatus,
			ConcurrentDictionary<string, T> statusDict)
		{
			if (statusDict.TryGetValue(deviceId, out var currentStatus) &&
				EqualityComparer<T>.Default.Equals(currentStatus, newStatus))
			{
				return;
			}

			statusDict[deviceId] = newStatus;
			OnDeviceStatusChanged(new DeviceStatusEventArgs(deviceId, newStatus));
		}

		private void UpdateRobotStatus(RobotTaskFeedBackDto taskStatus, RobotStatusDto deviceStatus)
		{
			bool taskStatusChanged = _robotTaskStatus == null ||
								   !_robotTaskStatus.Equals(taskStatus);
			bool deviceStatusChanged = _robotDeviceStatus == null ||
									 !_robotDeviceStatus.Equals(deviceStatus);

			// 更新Modbus连接状态
			bool isConnected = taskStatus.RobotProcessState != Domain.Equipment.Device.Robot.Enums.RobotProcessState.Disconnected;
			OnDeviceStatusChanged(new DeviceStatusEventArgs("ModbusConnection", isConnected));

			if (taskStatusChanged)
			{
				_robotTaskStatus = taskStatus;
				OnDeviceStatusChanged(new DeviceStatusEventArgs("RobotTask", taskStatus));
			}

			if (deviceStatusChanged)
			{
				_robotDeviceStatus = deviceStatus;
				OnDeviceStatusChanged(new DeviceStatusEventArgs("RobotDevice", deviceStatus));
			}
		}

		/// <summary>
		/// IO信号状态变化事件处理
		/// </summary>
		private void OnIOSignalStateChanged(object sender, IOSignalStateChangedEventArgs e)
		{
			try
			{
				// 特殊信号处理（如紧急停止信号等）
				if (IOSignalUtils.TryParseDISignalId(e.SignalId, out DISignalId diId))
				{
					if (diId == DISignalId.EmergencyStop)
					{
						bool state = (bool)e.NewState;
						OnDeviceStatusChanged(new DeviceStatusEventArgs("EmergencyStop", state));
					}
				}
				else if (IOSignalUtils.TryParseAISignalId(e.SignalId, out AISignalId aiId))
				{
					if (aiId == AISignalId.CondenserPressure)
					{
						double value = (double)e.NewState;
						OnDeviceStatusChanged(new DeviceStatusEventArgs("CondenserPressure", value));
					}
				}

				// 转发所有IO信号状态变化事件
				OnDeviceStatusChanged(new DeviceStatusEventArgs(e.SignalId, e.NewState));
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, $"处理IO信号状态变化事件异常: {e.SignalId}");
			}
		}

		protected virtual void OnDeviceStatusChanged(DeviceStatusEventArgs e)
		{
			try
			{
				DeviceStatusChanged?.Invoke(this, e);

				// 调用所有注册的回调函数
				foreach (var callback in _statusCallbacks)
				{
					try
					{
						_ = callback(e.DeviceId, e.Status);
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, $"设备状态回调执行异常: {ex.Message}");
					}
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "设备状态变化事件处理异常");
			}
		}

		/// <summary>
		/// 注册设备状态变化回调
		/// </summary>
		public void RegisterStatusCallback(Func<string, object, Task> callback)
		{
			if (callback != null)
			{

				_logger.LogInformation($"设备回调次数:{_statusCallbacks.Count}");
				_statusCallbacks.Add(callback);
			}
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_disposed) return;

			if (disposing)
			{
				_cts.Cancel();
				_cts.Dispose();

				// 取消订阅IO信号状态变化事件
				if (_ioSignalAppService != null)
				{
					_ioSignalAppService.SignalStateChanged -= OnIOSignalStateChanged;
				}
			}

			_disposed = true;
		}
	}
}